#pragma once 

#include <iostream>
#include <string>
#include <vector>

#include <cstring>

// 使用X来划分字符串
#define SEP "X"
#define SEP_LEN strlen(SEP)

void SpliteMessage(std::string& buffer, std::vector<std::string>* out)
{
    while (true)
    {
        auto pos = buffer.find(SEP);
        if (pos == std::string::npos) break; // 代表后面没有完整的报文了
        std::string message = buffer.substr(0, pos);
        buffer.erase(buffer.begin(), buffer.begin() + pos + SEP_LEN);
        out->push_back(message);
    }
}

std::string Encode(std::string& s)
{
    return s + SEP;
}

#define SPACE " "
#define SPACE_LEN strlen(SPACE)

class Request
{
public:
    std::string Serialize() // 序列化 -> "x_ op_ y_"
    {
        // 自己实现
        // 现成的方案
        std::string str;
        str = std::to_string(x_);
        str += SPACE;
        str += op_;
        str += SPACE;
        str += std::to_string(y_);
        return str;
    }

    bool Deserialize(const std::string& str) // 反序列化 "x_ op_ y_" -> 结构化数据
    {
        std::size_t left = str.find(SPACE);
        if (left == std::string::npos) return false;
        std::size_t right = str.rfind(SPACE);
        x_ = stoi(str.substr(0, left));
        y_ = stoi(str.substr(right + SPACE_LEN));
        op_ = str[left + SPACE_LEN];
        return true;
    }

public:
    Request(){}
    Request(int x, int y, char op)
        :x_(x)
        ,y_(y)
        ,op_(op)
    {}
    ~Request(){}
public:
    int x_;
    int y_;
    char op_;
};

class Response
{
public:
    std::string Serialize() // 序列化 -> "code_ result_"
    {
        std::string s;
        s = std::to_string(code_);
        s += SPACE;
        s += std::to_string(result_);
        return s;
    }

    bool Deserialize(const std::string& str) // 反序列化 "code_ result_" -> 结构化数据
    {
        std::size_t pos = str.find(SPACE);
        if (pos == std::string::npos) return false;
        code_ = stoi(str.substr(0, pos));
        result_ = stoi(str.substr(pos + SPACE_LEN));
        return true;
    }
public:
    Response(){}
    Response(int result, int code)
        :result_(result)
        ,code_(code)
    {}
    ~Response(){}
public:
    int result_; // 结果
    int code_;   // 结果状态码
};

static Response calculator(const Request &req) // 拿到结构化的请求，返回结构化的数据
{
    Response resp(0, 0);
    switch (req.op_)
    {
    case '+':
        resp.result_ = req.x_ + req.y_;
        break;
    case '-':
        resp.result_ = req.x_ - req.y_;
        break;
    case '*':
        resp.result_ = req.x_ * req.y_;
        break;
    case '/':
        if (0 == req.y_)
            resp.code_ = 1;
        else
            resp.result_ = req.x_ / req.y_;
        break;
    case '%':
        if (0 == req.y_)
            resp.code_ = 2;
        else
            resp.result_ = req.x_ % req.y_;
        break;
    default:
        resp.code_ = 3;
        break;
    }
    return resp;
}